package per.zqx.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Service;
import per.zqx.dto.Order;
import per.zqx.mapper.DispatcherMapper;
import per.zqx.pojo.Dispatcher;

import java.io.IOException;
import java.time.LocalDateTime;

/**
 * DispatcherServiceImpl,
 * //消费者事务不回滚生产事务，这类属于可靠事务一致性，生产事务可靠性保障消息最终发送成功，消费可靠性保证消费最终消费（无论是人工干预还是自己写的补偿机制），消费如果事务出问题可以自己写补偿机制
 * @author Sa, Zhang 2021-08-15 16:41
 */
@Service
public class DispatcherDLXCustomer {

    @Autowired
    DispatcherMapper dispatcherMapper;
    @RabbitListener(queues = "acid.dead.order.queue")
    public void receiveMsg(String orderMsg, Channel channel,@Header(AmqpHeaders.DELIVERY_TAG) Long tag) throws IOException {
        System.out.println("派单系统-死信队列收到订单 ====> " + orderMsg);
        try {
            JSONObject o = (JSONObject) JSONObject.parse(orderMsg);
            Order order = JSON.toJavaObject(o, Order.class);
            System.out.println(order);
            // 一定要考虑幂等性问题
                // 利用数据库，主键或者唯一键
                // 分布式锁解决幂等性问题
            Dispatcher dispatcher = dispatcherMapper.findByOrderId(order.getId());
            saveDispatcher(order);
            channel.basicAck(tag,false);
        }catch (Exception e){
            System.out.println("死信队列消息处理失败");
            System.out.println("请人工干预");
            System.out.println("短信通知");
            System.out.println("将消息转移到其他便于查看的地方存储");
            // 拒绝消息
            channel.basicNack(tag,false,false);
        }

    }
    public void saveDispatcher(Order order) {
        LocalDateTime now = LocalDateTime.now();
        Dispatcher dispatcher = new Dispatcher();
        dispatcher.setOrderId(order.getId());
        dispatcher.setBuyer(order.getBuyer());
        dispatcher.setCreateTime(now);
        dispatcher.setUpdateTime(now);
        dispatcherMapper.save(dispatcher);
    }
}
